# -*- coding: utf-8 -*-
"""
Compare async performance profiles between builds.
"""

import pstats
import json
import argparse
from pathlib import Path
from typing import Dict, Any

class ProfileComparator:
    """Compare performance profiles and detect regressions."""

    def compare_profiles(self, baseline_path: Path, current_path: Path) -> Dict[str, Any]:
        """Compare two performance profiles."""

        baseline_stats = pstats.Stats(str(baseline_path))
        current_stats = pstats.Stats(str(current_path))

        comparison: Dict[str, Any] = {
            'baseline_file': str(baseline_path),
            'current_file': str(current_path),
            'regressions': [],
            'improvements': [],
            'summary': {}
        }

        # Compare overall performance
        baseline_total_time = baseline_stats.total_tt
        current_total_time = current_stats.total_tt

        total_time_change = (
            (current_total_time - baseline_total_time) / baseline_total_time * 100
        )

        comparison['summary']['total_time_change'] = total_time_change

        # Compare function-level performance
        baseline_functions = self._extract_function_stats(baseline_stats)
        current_functions = self._extract_function_stats(current_stats)

        for func_name, baseline_time in baseline_functions.items():
            if func_name in current_functions:
                current_time: float = current_functions[func_name]
                change_percent = (current_time - baseline_time) / baseline_time * 100

                if change_percent > 20:  # 20% regression threshold
                    comparison['regressions'].append({
                        'function': func_name,
                        'baseline_time': baseline_time,
                        'current_time': current_time,
                        'change_percent': change_percent
                    })
                elif change_percent < -10:  # 10% improvement
                    comparison['improvements'].append({
                        'function': func_name,
                        'baseline_time': baseline_time,
                        'current_time': current_time,
                        'change_percent': change_percent
                    })

        return comparison


    def _extract_function_stats(self, stats: pstats.Stats) -> Dict[str, float]:
        """Extract function-level statistics from pstats.Stats."""

        functions = {}

        for func, stat in stats.stats.items():
            func_name = f"{func[0]}:{func[1]}:{func[2]}"
            tottime = stat[2]  # Extract the 'tottime' (total time spent in the given function)
            functions[func_name] = tottime

        return functions


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Compare performance profiles.")
    parser.add_argument("--baseline", type=Path, required=True, help="Path to the baseline profile.")
    parser.add_argument("--current", type=Path, required=True, help="Path to the current profile.")
    parser.add_argument("--output", type=Path, required=True, help="Path to the output comparison report.")

    args = parser.parse_args()

    comparator = ProfileComparator()
    comparison = comparator.compare_profiles(args.baseline, args.current)

    with open(args.output, 'w') as f:
        json.dump(comparison, f, indent=4)

    print(f"Comparison report saved to {args.output}")
